package cn.ibdsr.human.service.impl;

import cn.ibdsr.human.constant.*;
import cn.ibdsr.human.db.mapper.CompanyMapper;
import cn.ibdsr.human.db.mapper.JobMapper;
import cn.ibdsr.human.db.mapper.ServerInitMapper;
import cn.ibdsr.human.db.mapper.UserMapper;
import cn.ibdsr.human.db.model.Company;
import cn.ibdsr.human.db.model.Job;
import cn.ibdsr.human.db.model.ServerInit;
import cn.ibdsr.human.db.model.User;
import cn.ibdsr.human.exception.BizExceptionEnum;
import cn.ibdsr.human.exception.BusinessException;
import cn.ibdsr.human.service.CompanyService;
import cn.ibdsr.human.service.JobService;
import cn.ibdsr.human.transfer.UserDetailDTO;
import cn.ibdsr.human.transfer.job.*;
import cn.ibdsr.human.transfer.platform.LatestJobItem;
import cn.ibdsr.human.util.MybatisPlusPage;
import cn.ibdsr.human.warpper.CompanyResponseWarpper;
import cn.ibdsr.human.warpper.JobResponseWarpper;
import cn.ibdsr.human.warpper.UserDetailWarpper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @description:
 * @author: cdl
 * @email: iamcimon@qq.com
 * @date: 2021/8/4 9:48
 */

@Service
@Slf4j
public class JobServiceImpl implements JobService {
    @Resource
    private JobMapper jobMapper;
    @Resource
    private CompanyMapper companyMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CompanyService companyService;
    @Resource
    private ServerInitMapper serverInitMapper;
    /**
     * 保存工作信息
     *
     * @param userId
     * @param jobSaveDTO
     * @return
     */
    @Transactional
    @Override
    public Long publishJob(Long userId, JobSaveDTO jobSaveDTO) {

        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(BizExceptionEnum.USER_NOT_EXISTED);
        }
        if (user.getCompanyId() == null) {
            throw new BusinessException(BizExceptionEnum.COMPANY_NOT_IDENTIFICATION);
        }
        Company company = companyMapper.selectById(user.getCompanyId());
        if (company == null) {
            throw new BusinessException(BizExceptionEnum.COMPANY_NOT_IDENTIFICATION);
        }
        if (!company.getStatus().equals(CompanyStatusEnum.SUCCESS.getType())) {
            throw new BusinessException(BizExceptionEnum.COMPANY_NOT_SUCCESS_IDENTIFICATION);
        }
        Job job = new Job();
        job = JSONObject.parseObject(JSONObject.toJSONString(jobSaveDTO), Job.class);
        job.setCompanyId(company.getId());
        job.setCreateUser(userId);

        jobMapper.insert(job);

        if(jobSaveDTO.getIsPublish()){
            job.setModifyTime(LocalDateTime.now());
            jobMapper.updateById(job);
            updateJobCompanyRank(company.getId());
            companyService.computerJobCnt(job.getCompanyId(), userId,jobSaveDTO.getIsPublish() );
        }
        return job.getId();
    }

    /**
     * 更新企业的排序顺序
     * @param companyID
     */
    synchronized private void updateJobCompanyRank(Long companyID) {
        Long maxSortRank=jobMapper.selectMaxSortRank();
        if(maxSortRank==null)maxSortRank=0L;
        maxSortRank++;
        UpdateWrapper<Job> jobUpdateWrapper=new UpdateWrapper<>();
        jobUpdateWrapper.eq("is_deleted",IsDeleted.NORMAL.getCode());
        jobUpdateWrapper.eq("company_id",companyID);
        jobUpdateWrapper.set("sort_rank",maxSortRank);
        jobMapper.update(null,jobUpdateWrapper);
    }

    /**
     * 编辑工作岗位
     *
     * @param userId
     * @param jobSaveDTO
     * @return
     */
    @Transactional
    @Override
    public Long editJob(Long userId, JobSaveDTO jobSaveDTO) {

        Job job = jobMapper.selectById(jobSaveDTO.getId());
        if (job == null) {
            throw new BusinessException(BizExceptionEnum.NO_THIS_JOB);
        }
        if(jobSaveDTO.getIsPublish()==null){
            throw new BusinessException(BizExceptionEnum.REQUEST_PARAM_IS_ERROR);
        }
        Boolean first=job.getPublish();

        Job jobNew = JSONObject.parseObject(JSONObject.toJSONString(jobSaveDTO), Job.class);
        jobNew.setUpdateTime(LocalDateTime.now());
        jobNew.setUpdateUser(userId);
        jobMapper.updateById(jobNew);
        if(jobNew.getPublish()){
            jobNew.setModifyTime(LocalDateTime.now());
            updateJobCompanyRank(jobNew.getCompanyId());
        }
        if (!jobNew.getPublish().equals(first)) {
            companyService.computerJobCnt(job.getCompanyId(), userId, jobNew.getPublish());
        }
        return job.getId();
    }
    /**
     * 发布和取消发布
     * @param userId
     * @param jobSaveDTO
     * @return
     */
    @Transactional
    @Override
    public Long publishJobOrNot(Long userId, JobOperatorDTO jobSaveDTO) {
        Job job = jobMapper.selectById(jobSaveDTO.getId());
        if (job == null||job.getDeleted().equals(IsDeleted.DELETED.getCode()>0)) {
            throw new BusinessException(BizExceptionEnum.NO_THIS_JOB);
        }
        if (job.getPublish().equals(jobSaveDTO.getIsPublish())) {
            return job.getId();
        }

        if(jobSaveDTO.getIsPublish()){
            job.setModifyTime(LocalDateTime.now());
            updateJobCompanyRank(job.getCompanyId());
        }
        Job  tempJob=new Job();
        tempJob.setId(job.getId());
        tempJob.setUpdateUser(userId);
        tempJob.setUpdateTime(LocalDateTime.now());
        tempJob.setPublish(jobSaveDTO.getIsPublish());
        jobMapper.updateById(tempJob);
        companyService.computerJobCnt(job.getCompanyId(), userId, jobSaveDTO.getIsPublish());
        return job.getId();
    }
    /**
     * 删除工作
     * @param userId
     * @param id
     * @return
     */
    @Override
    public Long delete(Long userId, Long id) {
        Job job = jobMapper.selectById(id);
        if (job == null) {
            throw new BusinessException(BizExceptionEnum.NO_THIS_JOB);
        }
        if (job.getDeleted().equals(IsDeleted.DELETED.getCode())) {
            return job.getId();
        }
        if (job.getPublish().equals(PublishEnum.YES.getCode())) {
            throw new BusinessException(BizExceptionEnum.CANCEL_JOB);
        }
        job.setUpdateUser(userId);
        job.setUpdateTime(LocalDateTime.now());
        job.setDeleted(IsDeleted.DELETED.getCode()>0);
        jobMapper.updateById(job);
        return job.getId();
    }
    /**
     * 获取岗位详情信息
     *
     * @param id
     * @return
     */
    @Override
    public JobResponseDTO getJobDetail(Long id) {
        Job job = jobMapper.selectById(id);
        if (job == null||job.getDeleted().equals(IsDeleted.DELETED.getCode()>0)) {
            throw new BusinessException(BizExceptionEnum.NO_THIS_JOB);
        }
        JobResponseDTO jobResponseDTO = new JobResponseDTO();
        JSONObject jsonObject = (JSONObject) (new JobResponseWarpper(JSONObject.parseObject(JSONObject.toJSONString(job)),true)).warp();

        jobResponseDTO = JSONObject.parseObject(JSONObject.toJSONString(jsonObject), JobResponseDTO.class);
        return jobResponseDTO;
    }

    /**
     * 分页查询自己企业的工作信息
     *
     * @param jobQueryDTO
     * @return
     */
    @Override
    public JobListResponseDTO getJobList(JobQueryDTO jobQueryDTO) {
        if (jobQueryDTO.getPageNo() == null || jobQueryDTO.getPageNo() <= 0) {
            jobQueryDTO.setPageNo(1L);
        }
        if (jobQueryDTO.getPageSize() == null || jobQueryDTO.getPageSize() <= 0) {
            jobQueryDTO.setPageSize(BizConstants.DEFAULT_PAGE_SIZE);
        } else if (jobQueryDTO.getPageSize() > BizConstants.MAX_PAGE_SIZE) {
            throw new BusinessException(BizExceptionEnum.REQUEST_ERROR);
        }

        Page<JobResponseDTO> page = MybatisPlusPage.defaultNewPage(jobQueryDTO);
        List<JobResponseDTO> jobs = jobMapper.listByPage(page,jobQueryDTO.getGender(), jobQueryDTO.getCompanyId(), jobQueryDTO.getName(), jobQueryDTO.getIsPublish());
        // 创建返回结果
        Long pageIdex = page.getSize() * (page.getCurrent() - 1);
        List<JobResponseDTO> newJobs=new ArrayList<>();
        for (JobResponseDTO job : jobs) {
            pageIdex++;
            JSONObject jsonObject = (JSONObject) (new JobResponseWarpper(JSONObject.parseObject(JSONObject.toJSONString(job)),false)).warp();
            job = JSONObject.parseObject(JSONObject.toJSONString(jsonObject), JobResponseDTO.class);
            job.setIsPublishDes(PublishEnum.valueOf(job.getIsPublish() ? 1 : 0).getMessage());
            job.setUpdateTimeDes(job.getUpdateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            job.setRank(pageIdex);
            newJobs.add(job);
        }
        page.setRecords(newJobs);
        JobListResponseDTO jobListResponseDTO = new JobListResponseDTO();
        jobListResponseDTO.setPageNo(page.getCurrent());
        jobListResponseDTO.setPageSize(page.getSize());
        jobListResponseDTO.setTotalPage(page.getPages());
        jobListResponseDTO.setTotalCount(page.getTotal());
        jobListResponseDTO.setData(page.getRecords());
        return jobListResponseDTO;
    }


    /*获取求职列表
    * */
    @Override
    public JobCompanyResponseDTO getUserJobList(JobQueryDTO jobQueryDTO) {
        if (jobQueryDTO.getPageNo() == null || jobQueryDTO.getPageNo() <= 0) {
            jobQueryDTO.setPageNo(1L);
        }
        if (jobQueryDTO.getPageSize() == null || jobQueryDTO.getPageSize() <= 0) {
            jobQueryDTO.setPageSize(BizConstants.DEFAULT_PAGE_SIZE);
        } else if (jobQueryDTO.getPageSize() > BizConstants.MAX_PAGE_SIZE) {
            throw new BusinessException(BizExceptionEnum.REQUEST_ERROR);
        }

        Page<CompanyJobDTO> page = MybatisPlusPage.defaultNewPage(jobQueryDTO);
        List<CompanyJobDTO> companys = jobMapper.listUserJobByPage(page);

        HashSet<Long> companyIdsSet = new HashSet<>();
        for (CompanyJobDTO companyJobDTO : companys) {
            companyIdsSet.add(companyJobDTO.getId());
        }
        List<Long> companyIds = new ArrayList<>(companyIdsSet);
        List<Job> jobs=new ArrayList<>();
        if(companyIds.size()>0){
            QueryWrapper<Job> jobQueryWrapper=new QueryWrapper<>();
            jobQueryWrapper.eq("is_deleted",IsDeleted.NORMAL.getCode());
            jobQueryWrapper.eq("is_publish",PublishEnum.YES.getCode());
            jobQueryWrapper.in("company_id",companyIds);
            jobs=jobMapper.selectList(jobQueryWrapper);
        }

        HashMap<Long,List<Job>> companyMap=new HashMap<>();
        if (jobs.size() > 0) {
            Collections.sort(jobs, new Comparator<Job>() {
                @Override
                public int compare(Job o1, Job o2) {
                   if(o1.getModifyTime()!=null&&o2.getModifyTime()!=null&&o1.getModifyTime().equals(o2.getModifyTime())){
                       return o2.getUpdateTime().compareTo(o1.getUpdateTime());
                   }
                   return o2.getModifyTime().compareTo(o1.getModifyTime());
                }
            });
            for(int i=0;i<jobs.size();i++){
                Job job=jobs.get(i);
                if(companyMap.containsKey(job.getCompanyId())){
                    companyMap.get(job.getCompanyId()).add(job);
                }else {
                    List<Job> jobsTemp=new ArrayList<>();
                    jobsTemp.add(job);
                    companyMap.put(job.getCompanyId(),jobsTemp);
                }

            }

        }

        QueryWrapper<ServerInit> serverInitQueryWrapper=new QueryWrapper<>();
        serverInitQueryWrapper.eq("type", ServerInitEnum.SERVER_PHONE.getType());
        ServerInit serverInit=serverInitMapper.selectOne(serverInitQueryWrapper);
        if(serverInit==null){
            throw new BusinessException(BizExceptionEnum.SERVIER_INIT_ERROR);
        }
        String platformTelephone= ServerInitEnum.SERVER_PHONE.getDesc().replace("{phone}",serverInit.getConfigValue());


        List<CompanyJobDTO> newJobs=new ArrayList<>();
        // 创建返回结果
        for (CompanyJobDTO companyJobDTO : companys) {

            JSONObject jsonObject = (JSONObject) (new CompanyResponseWarpper(JSONObject.parseObject(JSONObject.toJSONString(companyJobDTO)),false)).warp();
            companyJobDTO = JSONObject.parseObject(JSONObject.toJSONString(jsonObject), CompanyJobDTO.class);
            companyJobDTO.setPlatformPhone(platformTelephone);
            companyJobDTO.setCode("No."+companyJobDTO.getCode());
            List<JobUserDTO> jobUserDTOList=new ArrayList<>();
            List<Job> jobList=companyMap.get(companyJobDTO.getId());
            if(jobList!=null&&jobList.size()>0){//这个企业下面有工作
                for(int i=0;i<jobList.size();i++){
                    Job tempJob=jobList.get(i);
                    JSONObject jobObject = (JSONObject) (new JobResponseWarpper(JSONObject.parseObject(JSONObject.toJSONString(tempJob)),false)).warp();
                    JobUserDTO jobUserDTO=JSONObject.parseObject(jobObject.toJSONString(),JobUserDTO.class);
                    jobUserDTO.setUpdateTimeDes(jobUserDTO.getUpdateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                    jobUserDTO.setPlatformPhone(platformTelephone);
                    jobUserDTOList.add(jobUserDTO);
                }
            }
            companyJobDTO.setJobCnt(jobUserDTOList.size());
            companyJobDTO.setData(jobUserDTOList);
            newJobs.add(companyJobDTO);
        }
        page.setRecords(newJobs);
        JobCompanyResponseDTO jobUserResponseDTO = new JobCompanyResponseDTO();
        jobUserResponseDTO.setPageNo(page.getCurrent());
        jobUserResponseDTO.setPageSize(page.getSize());
        jobUserResponseDTO.setTotalPage(page.getPages());
        jobUserResponseDTO.setTotalCount(page.getTotal());
        jobUserResponseDTO.setData(page.getRecords());
        return jobUserResponseDTO;
    }

    /**
     * 平台分页获取岗位信息
     * @param jobQueryDTO
     * @return
     */
    @Override
    public JobUserResponseDTO getPlatformJobList(JobQueryDTO jobQueryDTO) {
        if (jobQueryDTO.getPageNo() == null || jobQueryDTO.getPageNo() <= 0) {
            jobQueryDTO.setPageNo(1L);
        }
        if (jobQueryDTO.getPageSize() == null || jobQueryDTO.getPageSize() <= 0) {
            jobQueryDTO.setPageSize(BizConstants.DEFAULT_PAGE_SIZE);
        } else if (jobQueryDTO.getPageSize() > BizConstants.MAX_PAGE_SIZE) {
            throw new BusinessException(BizExceptionEnum.REQUEST_ERROR);
        }

        Page<JobUserDTO> page = MybatisPlusPage.defaultNewPage(jobQueryDTO);
        List<JobUserDTO> jobs = jobMapper.getPlatformJobList(page,
                jobQueryDTO.getCode(),jobQueryDTO.getName(),jobQueryDTO.getIsPublish()
        );
        List<JobUserDTO> jobsTemp=new ArrayList<>();
        // 创建返回结果
        for (JobUserDTO job : jobs) {
            JSONObject jsonObject = (JSONObject) (new JobResponseWarpper(JSONObject.parseObject(JSONObject.toJSONString(job)),false)).warp();
            job = JSONObject.parseObject(JSONObject.toJSONString(jsonObject), JobUserDTO.class);
            job.setIsPublishDes(PublishEnum.valueOf(job.getIsPublish() ? 1 : 0).getMessage());
            job.setUpdateTimeDes(job.getUpdateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            jobsTemp.add(job);
        }
        page.setRecords(jobsTemp);
        JobUserResponseDTO jobUserResponseDTO = new JobUserResponseDTO();
        jobUserResponseDTO.setPageNo(page.getCurrent());
        jobUserResponseDTO.setPageSize(page.getSize());
        jobUserResponseDTO.setTotalPage(page.getPages());
        jobUserResponseDTO.setTotalCount(page.getTotal());
        jobUserResponseDTO.setData(page.getRecords());
        return jobUserResponseDTO;
    }

    /**
     * 获取最新的工作岗位数据
     * @return
     */
    @Override
    public List<LatestJobItem> getLatestJob() {
        List<LatestJobItem> jobs = jobMapper.getLatestJobList();
        for(int i=0;i<jobs.size();i++){
            LatestJobItem latestJobItem=jobs.get(i);
            latestJobItem.setCode("No."+latestJobItem.getCode());
            latestJobItem.setRank(i+1L);
        }
        return jobs;
    }
}
